﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using SalesPoint.Commands;
using SalesPoint.Model;
using SalesPoint.Security;
using Xtensive.Orm;
using Xtensive.Orm.Security;
using IPrincipal = Xtensive.Orm.Security.IPrincipal;

namespace SalesPoint.ViewModels
{
  public class LoginEventArgs : EventArgs
  {
    public IPrincipal Principal { get; private set; }

    public LoginEventArgs(IPrincipal principal)
    {
      Principal = principal;
    }
  }

  internal class LoginViewModel : ViewModelBase
  {
    private Employee employee;
    private string userName;
    private string password;
    private DelegateCommand loginCommand;

    public event EventHandler<LoginEventArgs> SuccessfulLogin;

    public ICommand LoginCommand
    {
      get 
      {
        if (loginCommand != null)
          return loginCommand;

        loginCommand = new DelegateCommand(Login, CanLogin);
        return loginCommand;
      }
    }

    public IList<Employee> Employees { get; private set; }

    public Employee Employee
    {
      get { return employee; }
      set
      {
        employee = value;
        OnPropertyChanged("Employee");
        UserName = employee.Name;
        Password = employee.PasswordHash;
      }
    }

    public string UserName
    {
      get
      {
        return userName;
      }
      set
      {
        userName = value;
        OnPropertyChanged("UserName");
      }
    }

    public string Password
    {
      get
      {
        return password;
      }
      set
      {
        password = value;
        OnPropertyChanged("Password");
      }
    }

    private void InvokeSuccessfulLogin(LoginEventArgs e)
    {
      var handler = SuccessfulLogin;
      if (handler != null) handler(this, e);
    }

    private bool CanLogin()
    {
      return !(string.IsNullOrEmpty(UserName) || string.IsNullOrEmpty(Password));
    }

    private void Login()
    {
      var principal = Session.Authenticate(UserName, Password);
      if (principal != null)
        InvokeSuccessfulLogin(new LoginEventArgs(principal));
      else
        MessageBox.Show("Log in is unsuccessful", "Log in error", MessageBoxButton.OK, MessageBoxImage.Error);
    }

    public LoginViewModel(Session session)
      : base(session)
    {
      Employees = session.Query.All<Employee>()
        .OrderBy(e => e.Address.City)
        .ToList();
      Employee = Employees.First();
    }
  }
}